package com.ztorn.fiscale.controller;

import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;

import com.ztorn.common.core.utils.poi.ExcelUtil;
import com.ztorn.common.core.web.controller.BaseController;
import com.ztorn.common.core.web.domain.AjaxResult;
import com.ztorn.common.core.web.page.TableDataInfo;
import com.ztorn.common.log.annotation.Log;
import com.ztorn.common.log.enums.BusinessType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ztorn.fiscale.domain.FiscaleCustomsDeclaration;
import com.ztorn.fiscale.domain.FiscaleCustomsDeclarationOrder;
import com.ztorn.fiscale.domain.FiscaleCustomsStatusHistory;
import com.ztorn.fiscale.service.IFiscaleCustomsDeclarationService;
import com.ztorn.fiscale.service.IFiscaleOrderService;
import com.ztorn.fiscale.service.IFiscaleCustomsStatusHistoryService;

/**
 * 报关单管理Controller
 *
 * @author ztorn
 * @date 2025-01-19
 */
@RestController
@RequestMapping("/declaration")
public class FiscaleCustomsDeclarationController extends BaseController
{
    @Autowired
    private IFiscaleCustomsDeclarationService fiscaleCustomsDeclarationService;
    
    @Autowired
    private IFiscaleOrderService fiscaleOrderService;
    
    @Autowired
    private IFiscaleCustomsStatusHistoryService fiscaleCustomsStatusHistoryService;

    /**
     * 查询报关单管理列表
     */
    @PreAuthorize("@ss.hasPermi('fiscale:declaration:list')")
    @GetMapping("/list")
    public TableDataInfo list(FiscaleCustomsDeclaration fiscaleCustomsDeclaration)
    {
        startPage();
        List<FiscaleCustomsDeclaration> list = fiscaleCustomsDeclarationService.selectFiscaleCustomsDeclarationList(fiscaleCustomsDeclaration);
        return getDataTable(list);
    }

    /**
     * 导出报关单管理列表
     */
    @PreAuthorize("@ss.hasPermi('fiscale:declaration:export')")
    @Log(title = "报关单管理", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, FiscaleCustomsDeclaration fiscaleCustomsDeclaration)
    {
        List<FiscaleCustomsDeclaration> list = fiscaleCustomsDeclarationService.selectFiscaleCustomsDeclarationList(fiscaleCustomsDeclaration);
        ExcelUtil<FiscaleCustomsDeclaration> util = new ExcelUtil<FiscaleCustomsDeclaration>(FiscaleCustomsDeclaration.class);
        util.exportExcel(response, list, "报关单管理数据");
    }

    /**
     * 获取报关单管理详细信息
     */
    @PreAuthorize("@ss.hasPermi('fiscale:declaration:query')")
    @GetMapping(value = "/{declarationId}")
    public AjaxResult getInfo(@PathVariable("declarationId") Long declarationId)
    {
        return success(fiscaleCustomsDeclarationService.selectFiscaleCustomsDeclarationByDeclarationId(declarationId));
    }

    /**
     * 新增报关单管理
     */
    @PreAuthorize("@ss.hasPermi('fiscale:declaration:add')")
    @Log(title = "报关单管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody FiscaleCustomsDeclaration fiscaleCustomsDeclaration)
    {
        int result = fiscaleCustomsDeclarationService.insertFiscaleCustomsDeclaration(fiscaleCustomsDeclaration);
        if (result > 0) {
            return success(fiscaleCustomsDeclaration);
        } else {
            return error();
        }
    }

    /**
     * 修改报关单管理
     */
    @PreAuthorize("@ss.hasPermi('fiscale:declaration:edit')")
    @Log(title = "报关单管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody FiscaleCustomsDeclaration fiscaleCustomsDeclaration)
    {
        return toAjax(fiscaleCustomsDeclarationService.updateFiscaleCustomsDeclaration(fiscaleCustomsDeclaration));
    }

    /**
     * 删除报关单管理
     */
    @PreAuthorize("@ss.hasPermi('fiscale:declaration:remove')")
    @Log(title = "报关单管理", businessType = BusinessType.DELETE)
	@DeleteMapping("/{declarationIds}")
    public AjaxResult remove(@PathVariable Long[] declarationIds)
    {
        try {
            return toAjax(fiscaleCustomsDeclarationService.deleteFiscaleCustomsDeclarationByDeclarationIds(declarationIds));
        } catch (Exception e) {
            logger.error("删除报关单失败", e);
            return error(e.getMessage());
        }
    }

    /**
     * 根据报关单号查询报关单
     */
    @PreAuthorize("@ss.hasPermi('fiscale:declaration:query')")
    @GetMapping("/getByDeclarationNo/{declarationNo}")
    public AjaxResult getByDeclarationNo(@PathVariable("declarationNo") String declarationNo)
    {
        return success(fiscaleCustomsDeclarationService.selectFiscaleCustomsDeclarationByDeclarationNo(declarationNo));
    }

    /**
     * 生成报关单号
     */
    @PreAuthorize("@ss.hasPermi('fiscale:declaration:add')")
    @GetMapping("/generateDeclarationNo")
    public AjaxResult generateDeclarationNo()
    {
        return success(fiscaleCustomsDeclarationService.generateDeclarationNo());
    }

    /**
     * 从订单创建报关单（增强版，支持完整的生成流程）
     */
    @PreAuthorize("@ss.hasPermi('fiscale:declaration:generateFromOrder')")
    @Log(title = "从订单生成报关单", businessType = BusinessType.INSERT)
    @PostMapping("/generateFromOrders")
    public AjaxResult generateFromOrders(@RequestBody Map<String, Object> params)
    {
        try {
            // 提取订单ID列表
            @SuppressWarnings("unchecked")
            List<Integer> orderIdList = (List<Integer>) params.get("orderIds");
            Long[] orderIds = orderIdList.stream()
                    .mapToLong(Integer::longValue)
                    .boxed()
                    .toArray(Long[]::new);

            // 提取报关单基本信息
            @SuppressWarnings("unchecked")
            Map<String, Object> declarationInfo = (Map<String, Object>) params.get("declarationInfo");

            // 调用生成服务（需要创建新的服务方法）
            // 这里先使用现有的方法，后续可以扩展
            FiscaleCustomsDeclaration declaration = new FiscaleCustomsDeclaration();
            declaration.setDeclarationType((String) declarationInfo.get("declarationType"));
            declaration.setTradeMode((String) declarationInfo.get("tradeMode"));
            declaration.setTransportMode((String) declarationInfo.get("transportMode"));
            declaration.setDeparturePort((String) declarationInfo.get("departurePort"));
            declaration.setDestinationPort((String) declarationInfo.get("destinationPort"));
            declaration.setCurrency((String) declarationInfo.getOrDefault("currency", "USD"));
            declaration.setRemark((String) declarationInfo.get("remark"));

            // 处理日期
            if (declarationInfo.get("exportDate") != null) {
                declaration.setExportDate(new java.text.SimpleDateFormat("yyyy-MM-dd").parse((String) declarationInfo.get("exportDate")));
            }

            int result = fiscaleCustomsDeclarationService.createDeclarationFromOrders(declaration, orderIds);
            if (result > 0) {
                return success("报关单生成成功"+declaration.getDeclarationId());
            } else {
                return error("报关单生成失败");
            }
        } catch (Exception e) {
            logger.error("生成报关单失败", e);
            return error("报关单生成失败：" + e.getMessage());
        }
    }

    /**
     * 从订单创建报关单（兼容旧版前端）
     */
    @PreAuthorize("@ss.hasPermi('fiscale:declaration:add')")
    @Log(title = "从订单创建报关单", businessType = BusinessType.INSERT)
    @PostMapping("/createFromOrders")
    public AjaxResult createFromOrders(@RequestBody Map<String, Object> params)
    {
        try {
            // 提取订单ID列表
            @SuppressWarnings("unchecked")
            List<Integer> orderIdList = (List<Integer>) params.get("orderIds");
            
            // 如果orderIds是字符串，则需要分割
            if (orderIdList == null) {
                String orderIdsStr = (String) params.get("orderIds");
                if (orderIdsStr != null && !orderIdsStr.isEmpty()) {
                    String[] orderIdStrArray = orderIdsStr.split(",");
                    orderIdList = new java.util.ArrayList<>();
                    for (String orderIdStr : orderIdStrArray) {
                        try {
                            orderIdList.add(Integer.valueOf(orderIdStr.trim()));
                        } catch (NumberFormatException e) {
                            // 忽略无效的ID
                        }
                    }
                }
            }
            
            if (orderIdList == null || orderIdList.isEmpty()) {
                return error("未提供有效的订单ID");
            }
            
            Long[] orderIds = orderIdList.stream()
                    .mapToLong(Integer::longValue)
                    .boxed()
                    .toArray(Long[]::new);

            // 创建报关单对象
            FiscaleCustomsDeclaration declaration = new FiscaleCustomsDeclaration();
            declaration.setDeclarationType((String) params.get("declarationType"));
            declaration.setTradeMode((String) params.get("tradeMode"));
            declaration.setTransportMode((String) params.get("transportMode"));
            declaration.setDeparturePort((String) params.get("departurePort"));
            declaration.setDestinationPort((String) params.get("destinationPort"));
            declaration.setCurrency((String) params.getOrDefault("currency", "USD"));
            declaration.setRemark((String) params.get("remark"));
            
            // 处理总金额
            Object totalAmountObj = params.get("totalAmount");
            if (totalAmountObj != null) {
                if (totalAmountObj instanceof Number) {
                    declaration.setTotalAmount(new java.math.BigDecimal(totalAmountObj.toString()));
                } else if (totalAmountObj instanceof String) {
                    try {
                        declaration.setTotalAmount(new java.math.BigDecimal((String) totalAmountObj));
                    } catch (NumberFormatException e) {
                        // 忽略无效金额
                    }
                }
            }

            // 处理日期
            Object exportDateObj = params.get("exportDate");
            if (exportDateObj != null) {
                if (exportDateObj instanceof String) {
                    try {
                        declaration.setExportDate(new java.text.SimpleDateFormat("yyyy-MM-dd").parse((String) exportDateObj));
                    } catch (java.text.ParseException e) {
                        // 忽略无效日期
                    }
                }
            }

            int result = fiscaleCustomsDeclarationService.createDeclarationFromOrders(declaration, orderIds);
            if (result > 0) {
                return success("报关单生成成功"+declaration.getDeclarationId());
            } else {
                return error("报关单生成失败");
            }
        } catch (Exception e) {
            logger.error("生成报关单失败", e);
            return error("报关单生成失败：" + e.getMessage());
        }
    }

    /**
     * 提交报关单
     */
    @PreAuthorize("@ss.hasPermi('fiscale:declaration:submit')")
    @Log(title = "提交报关单", businessType = BusinessType.UPDATE)
    @PutMapping("/submit/{declarationId}")
    public AjaxResult submit(@PathVariable("declarationId") Long declarationId)
    {
        return toAjax(fiscaleCustomsDeclarationService.submitCustomsDeclaration(declarationId));
    }

    /**
     * 审批报关单
     */
    @PreAuthorize("@ss.hasPermi('fiscale:declaration:approve')")
    @Log(title = "审批报关单", businessType = BusinessType.UPDATE)
    @PutMapping("/approve")
    public AjaxResult approve(@RequestBody Map<String, Object> params)
    {
        Long declarationId = Long.valueOf(params.get("declarationId").toString());
        String customsStatus = (String) params.get("customsStatus");
        String customsOfficer = (String) params.get("customsOfficer");
        return toAjax(fiscaleCustomsDeclarationService.approveCustomsDeclaration(declarationId, customsStatus, customsOfficer));
    }

    /**
     * 批量更新报关单状态
     */
    @PreAuthorize("@ss.hasPermi('fiscale:declaration:edit')")
    @Log(title = "批量更新报关单状态", businessType = BusinessType.UPDATE)
    @PutMapping("/batchUpdateStatus")
    public AjaxResult batchUpdateStatus(@RequestBody Map<String, Object> params)
    {
        @SuppressWarnings("unchecked")
        List<Integer> declarationIdList = (List<Integer>) params.get("declarationIds");
        Long[] declarationIds = declarationIdList.stream()
                .mapToLong(Integer::longValue)
                .boxed()
                .toArray(Long[]::new);
        String customsStatus = (String) params.get("customsStatus");
        return toAjax(fiscaleCustomsDeclarationService.batchUpdateCustomsStatus(declarationIds, customsStatus));
    }

    /**
     * 智能填充商品信息
     */
    @PreAuthorize("@ss.hasPermi('fiscale:declaration:generate')")
    @GetMapping("/autoFill/{productSku}")
    public AjaxResult autoFillProductInfo(@PathVariable("productSku") String productSku)
    {
        // 这里调用智能填充服务，暂时返回模拟数据
        try {
            Map<String, Object> productInfo = new java.util.HashMap<>();
            productInfo.put("productName", "模拟商品名称");
            productInfo.put("productNameEn", "Simulated Product Name");
            productInfo.put("hsCode", "12345678");
            productInfo.put("specification", "模拟规格");
            productInfo.put("unit", "PCS");

            return success("智能填充成功"+productInfo);
        } catch (Exception e) {
            logger.error("智能填充失败", e);
            return error("智能填充失败：" + e.getMessage());
        }
    }

    /**
     * 数据校验
     */
    @PreAuthorize("@ss.hasPermi('fiscale:declaration:validate')")
    @Log(title = "报关单数据校验", businessType = BusinessType.OTHER)
    @PostMapping("/validate")
    public AjaxResult validateDeclaration(@RequestBody FiscaleCustomsDeclaration declaration)
    {
        try {
            // 这里调用数据校验服务，暂时返回模拟结果
            List<Map<String, Object>> errors = new java.util.ArrayList<>();

            // 模拟校验逻辑
            if (declaration.getDeparturePort() == null || declaration.getDeparturePort().isEmpty()) {
                Map<String, Object> error = new java.util.HashMap<>();
                error.put("field", "departurePort");
                error.put("message", "启运港不能为空");
                errors.add(error);
            }

            if (errors.isEmpty()) {
                return success("数据校验通过");
            } else {
                return error("数据校验失败").put("errors", errors);
            }
        } catch (Exception e) {
            logger.error("数据校验失败", e);
            return error("数据校验失败：" + e.getMessage());
        }
    }

    /**
     * 申报到海关
     */
    @PreAuthorize("@ss.hasPermi('fiscale:declaration:submitToCustoms')")
    @Log(title = "申报报关单到海关", businessType = BusinessType.UPDATE)
    @PostMapping("/submitToCustoms/{declarationId}")
    public AjaxResult submitToCustoms(@PathVariable("declarationId") Long declarationId)
    {
        try {
            // 模拟申报逻辑
            FiscaleCustomsDeclaration declaration = fiscaleCustomsDeclarationService.selectFiscaleCustomsDeclarationByDeclarationId(declarationId);
            if (declaration == null) {
                return error("报关单不存在");
            }

            // 模拟成功申报
            String preEntryNo = "BGD" + System.currentTimeMillis();
            
            // 更新报关单状态和预录入编号
            declaration.setPreEntryNo(preEntryNo);
            declaration.setCustomsStatus("submitted");
            fiscaleCustomsDeclarationService.updateFiscaleCustomsDeclaration(declaration);
            
            // 更新相关订单的状态为"报关中"
            if (declaration.getDeclarationOrderList() != null) {
                Long[] orderIds = declaration.getDeclarationOrderList().stream()
                    .map(FiscaleCustomsDeclarationOrder::getOrderId)
                    .toArray(Long[]::new);
                if (orderIds.length > 0) {
                    fiscaleOrderService.batchUpdateCustomsStatus(orderIds, "declaring");
                }
            }
            
            return success("申报成功，预录入编号：" + preEntryNo);
        } catch (Exception e) {
            logger.error("申报失败", e);
            return error("申报失败：" + e.getMessage());
        }
    }

    /**
     * 手动刷新报关单状态
     */
    @PreAuthorize("@ss.hasPermi('fiscale:declaration:queryStatus')")
    @Log(title = "刷新报关单状态", businessType = BusinessType.UPDATE)
    @PostMapping("/refreshStatus/{declarationId}")
    public AjaxResult refreshStatus(@PathVariable("declarationId") Long declarationId)
    {
        try {
            // 模拟状态刷新
            FiscaleCustomsDeclaration declaration = fiscaleCustomsDeclarationService.selectFiscaleCustomsDeclarationByDeclarationId(declarationId);
            if (declaration == null) {
                return error("报关单不存在");
            }

            return success("状态刷新成功，当前状态：" + declaration.getCustomsStatus());
        } catch (Exception e) {
            logger.error("刷新状态失败", e);
            return error("刷新状态失败：" + e.getMessage());
        }
    }

    /**
     * 查看海关回执
     */
    @PreAuthorize("@ss.hasPermi('fiscale:declaration:viewReceipt')")
    @GetMapping("/receipt/{declarationId}")
    public AjaxResult getCustomsReceipt(@PathVariable("declarationId") Long declarationId)
    {
        try {
            FiscaleCustomsDeclaration declaration = fiscaleCustomsDeclarationService.selectFiscaleCustomsDeclarationByDeclarationId(declarationId);
            if (declaration == null) {
                return error("报关单不存在");
            }

            // 模拟回执数据
            Map<String, Object> receiptData = new java.util.HashMap<>();
            receiptData.put("preEntryNo", declaration.getPreEntryNo() != null ? declaration.getPreEntryNo() : "无预录入编号");
            receiptData.put("status", declaration.getCustomsStatus());
            receiptData.put("receiptTime", new java.util.Date());
            receiptData.put("message", "报关单处理正常");
            receiptData.put("rawData", "{模拟原始报文数据}");

            return success(receiptData);
        } catch (Exception e) {
            logger.error("获取回执失败", e);
            return error("获取回执失败：" + e.getMessage());
        }
    }

    /**
     * 下载结关单
     */
    @PreAuthorize("@ss.hasPermi('fiscale:declaration:downloadClearance')")
    @Log(title = "下载结关单", businessType = BusinessType.OTHER)
    @GetMapping("/downloadClearance/{declarationId}")
    public AjaxResult downloadClearanceDocument(@PathVariable("declarationId") Long declarationId)
    {
        try {
            FiscaleCustomsDeclaration declaration = fiscaleCustomsDeclarationService.selectFiscaleCustomsDeclarationByDeclarationId(declarationId);
            if (declaration == null) {
                return error("报关单不存在");
            }

            if (!"cleared".equals(declaration.getCustomsStatus())) {
                return error("该报关单尚未结关，无法下载结关单");
            }

            // 模拟结关单下载
            Map<String, Object> result = new java.util.HashMap<>();
            result.put("fileUrl", "https://example.com/clearance/" + declaration.getDeclarationNo() + ".pdf");
            result.put("fileName", "结关单_" + declaration.getDeclarationNo() + ".pdf");

            return success("结关单下载成功"+result);
        } catch (Exception e) {
            logger.error("下载结关单失败", e);
            return error("下载结关单失败：" + e.getMessage());
        }
    }

    /**
     * 获取报关单状态历史
     */
    @PreAuthorize("@ss.hasPermi('fiscale:declaration:tracking')")
    @GetMapping("/statusHistory/{declarationId}")
    public AjaxResult getStatusHistory(@PathVariable("declarationId") Long declarationId)
    {
        try {
            List<FiscaleCustomsStatusHistory> statusHistory = fiscaleCustomsStatusHistoryService.selectFiscaleCustomsStatusHistoryListByDeclarationId(declarationId);
            return success(statusHistory);
        } catch (Exception e) {
            logger.error("获取状态历史失败", e);
            return error("获取状态历史失败：" + e.getMessage());
        }
    }
}
